package ch.ethz.fcl.metrobuzz.controller.gui.twl;

import java.util.ArrayList;

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

import ch.ethz.fcl.metrobuzz.controller.MBController;
import ch.ethz.fcl.metrobuzz.controller.external.ActionEvent;
import ch.ethz.fcl.metrobuzz.controller.external.mouse.MouseEvent;
import ch.ethz.fcl.metrobuzz.controller.external.mouse.MouseListener;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Rectangle;
import de.matthiasmann.twl.GUI;
import de.matthiasmann.twl.Widget;
import de.matthiasmann.twl.input.Input;

public class TWLMouseInputHandler implements Input {
	@SuppressWarnings("unused")
	private MBController control;

	private boolean wasActive;
	private ArrayList<Widget> widgets = null;

	private Widget selectedWidget = null;

	public TWLMouseInputHandler(MBController control) {
		this.control = control;
	}

	public TWLMouseInputHandler(MBController control, Widget... input) {
		this.control = control;

		widgets = new ArrayList<Widget>();
		for (Widget w : input)
			widgets.add(w);
	}

	public void addListenWidget(Widget... input) {
		if (widgets == null)
			widgets = new ArrayList<Widget>();
		for (Widget w : input)
			widgets.add(w);
	}

	public void handleMouse(MouseEvent event) {
		if (event.getAction() == ActionEvent.ACTION_DOWN
				|| event.getAction() == ActionEvent.ACTION_DOUBLECLICK) {
			for (Widget w : widgets)
				if (w.isVisible()) {
					int right = w.getRight();
					int bottom = w.getBottom();
					int left = right - w.getWidth();
					int top = bottom - w.getHeight();

					Rectangle widgetArea = new Rectangle(left - 10, top - 10,
							right + 10, bottom + 10);

					if (widgetArea.contains(new Point2D(Mouse.getX(), Display
							.getHeight() - Mouse.getY()))) {
						selectedWidget = w;
						break;
					}
				}
		}
		if (event.getAction() == ActionEvent.ACTION_DRAG
				&& selectedWidget != null) {
			ActionEvent.DRAG_UPDATE = false;
		}
		if (event.getAction() == ActionEvent.ACTION_UP) {
			selectedWidget = null;
			ActionEvent.DRAG_UPDATE = true;
		}
	}

	public boolean pollInput(GUI gui) {
		boolean active = Display.isActive();
		if (wasActive && !active) {
			wasActive = false;
			return false;
		}
		wasActive = active;

		if (Mouse.isCreated()) {
			while (Mouse.next()) {
				gui.handleMouse(Mouse.getEventX(),
						gui.getHeight() - Mouse.getEventY() - 1,
						Mouse.getEventButton(), Mouse.getEventButtonState());

				// release left mouse click immediately to prevent unwanted long
				// press
				if (Mouse.getEventButton() == 0 && Mouse.getEventButtonState())
					gui.handleMouse(Mouse.getEventX(),
							gui.getHeight() - Mouse.getEventY() - 1,
							Mouse.getEventButton(), false);

				int wheelDelta = Mouse.getEventDWheel();
				if (wheelDelta != 0) {
					boolean wheelHandled = gui
							.handleMouseWheel(wheelDelta / 120);
					MouseListener.zoomUpdate = !wheelHandled;
				}
			}
		}

		return true;
	}
}
